using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace RollManager.Library.ActionSteps
{
    [Serializable]
    public class CheckWebPageStep : ActionStep
    {
        public string m_url;
        public string m_expectedText;
        public int m_port = 80;

        [DisplayName("Expected Text")]
        [Description("The text to find in the results of the URL.")]
        public string ExpectedText
        {
            get
            {
                return m_expectedText;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "ExpectedText cannot be empty." );
                }
                else
                {
                    m_expectedText = value.Trim();
                }
            }
        }

        [Description("The port to use for the web request.")]
        public int Port
        {
            get
            {
                return m_port;
            }
            set
            {
                m_port = value;
            }
        }

        [Description("The URL to be checked.")]
        public string Url
        {
            get
            {
                return m_url;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Url cannot be empty." );
                }
                else
                {
                    m_url = value.Trim();
                }
            }
        }

        public override string Name
        {
            get { return "Check Web Page"; }
        }

        protected override void Run()
        {
            string address = getCurrentServerAddress();
            Uri uri = new Uri( m_url );

            string response = null;

            // Open TCP socket, send request, and read response.
            using( TcpClient client = new TcpClient( address, m_port ) )
            {
                using( NetworkStream stream = client.GetStream() )
                {
                    // Write get request.
                    Byte[] msgBytes = Encoding.ASCII.GetBytes( string.Format( "GET {0} HTTP/1.0\r\nHost: {1}\r\n\r\n", 
                        uri.PathAndQuery, uri.Host ) );
                    stream.Write( msgBytes, 0, msgBytes.Length );

                    // Read back response.
                    using( StreamReader reader = new StreamReader( stream ) )
                    {
                        response = reader.ReadToEnd();
                    }
                }
            }

            if( !response.Contains( m_expectedText ) )
            {
                throw new Exception( string.Format( "{0} didn't contain expected text: {1}", m_url, response ) );
            }
        }

        protected override void Simulate()
        {
            Progress.AddFormat( "Simulated checking of {0} ({1}:{2}).", m_url, getCurrentServerAddress(), m_port );
        }

        private string getCurrentServerAddress()
        {
            return Dns.GetHostAddresses( CurrentServer )[ 0 ].ToString();
        }
    }
}
